﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using ControlYSeguimiento.Domain;
using ControlYSeguimiento.Logging;
using log4net;
using log4net.Config;

namespace ControlYSeguimiento_Web_App
{
    /// <summary>
    /// Summary description for ControlYSeguimiento
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class ControlYSeguimiento : System.Web.Services.WebService
    {
        [WebMethod]
        public int UpdateCoordinates(string imei,
                                        string userName,
                                        string latitude,
                                        string longitude,
                                        string course,
                                        string altitude,
                                        string speed,
                                        string batteryLevel
                                    )
        {
            Target currentTarget = null;

            try
            {
                Logger.Instance.Info(this,"Buscando target para " + userName + " con IMEI " + imei);
                currentTarget = Facade.Instance.GetTargetFromCustomerAndImei(userName, imei);
            }
            catch (Exception ex)
            {
                Logger.Instance.Fatal(this,"Excepcion: " + ex.Message);
                Logger.Instance.Fatal(this,"Stack Trace: " + ex.StackTrace);
            }

            if (currentTarget == null)
            {
                Logger.Instance.Fatal(this,"No se encontro ningun blanco con el IMEI =" + imei + "y nombre de usuario " + userName);
                throw new Exception("No se encontro ningun blanco con el IMEI =" + imei + "y nombre de usuario " + userName);
            }

            currentTarget.CurrentAltitude = altitude;
            currentTarget.CurrentCooridinate = new Coordinate(latitude, longitude);
            currentTarget.CurrentCourse = course;
            currentTarget.CurrentSpeed = speed;
            currentTarget.CurrentBatteryLevel = batteryLevel;

            Logger.Instance.Info(this,"Actualizando coordenadas " + altitude + " - " + latitude + " - " + longitude + " - " + course + " - " + speed+ " - "+batteryLevel);
            try
            {
                Transaction newTran = new Transaction();
                newTran.Date = DateTime.Now;
                newTran.CustomerAssociated = currentTarget.Customer;
                newTran.TargetAssociated = currentTarget;
                newTran.Type = TransactionType.UpdateCoordinatesType;
                newTran.UserAssociated = null;
                newTran.Value1 = currentTarget.CurrentAltitude;
                newTran.Value2 = currentTarget.CurrentCooridinate.Latitude;
                newTran.Value3 = currentTarget.CurrentCooridinate.Longitude;
                newTran.Value4 = currentTarget.CurrentCourse;
                newTran.Value5 = currentTarget.CurrentSpeed;
                newTran.Value6 = currentTarget.CurrentBatteryLevel;

                if (currentTarget.Customer.Enable == false) { Logger.Instance.Warn(this,"El cliente asociado al blanco obtenido esta DESHABILITADO (-1)"); newTran.Result = "01"; }
                else if (currentTarget.Device.Enable == false) { Logger.Instance.Warn(this,"El dispositivo asociado al blanco obtenido esta DESHABILITADO (-2)"); newTran.Result = "02"; }
                else { newTran.Result = "00"; }

                Facade.Instance.CreateTransaction(newTran);

                return (Convert.ToInt32(newTran.Result) * -1);
            }
            catch (Exception ex)
            {
                Logger.Instance.Fatal(this,"Excepcion: " + ex.Message);
                Logger.Instance.Fatal(this,"Stack Trace: " + ex.StackTrace);
                return -3;
            }
        }

        /// <summary>
        /// Actualiza las coordenadas y los datos del dispositivo a través de su IMEI. Funciona para la versión de 
        /// las app de los dispositivos donde NO se requiere enviar el email del usuario.
        /// </summary>
        /// <param name="imei">IMEI del dispositivo</param>
        /// <param name="code">Codigo aleatorio del dispositivo</param>
        /// <param name="latitude">Latitud del dispositivo</param>
        /// <param name="longitude">Longitud del dispositivo</param>
        /// <param name="course">Curso del dispositivo </param>
        /// <param name="altitude">altitud del dispositivo</param>
        /// <param name="speed">Velocidad del dispositivo</param>
        /// <param name="batteryLevel">Bateria del dispositivo</param>
        /// <returns>Int con el codigo del resultado de la operacion</returns>        
        [WebMethod]
        public int UpdateCoordinatesV2(string imei,    
                                        string code,                        
                                        string latitude,
                                        string longitude,
                                        string course,
                                        string altitude,
                                        string speed,
                                        string batteryLevel
                                    )
        {
            if (Facade.Instance.ValidateImeiAndCode(imei,code) == false)
            {
                throw new Exception("No se valido el IMEI = " + imei + " con codigo "+code);
            }
            else
            {
                #region Obtener Target
                Target currentTarget = null;
               
                try
                {
                    Logger.Instance.Info(this, "Buscando target con IMEI " + imei);
                    currentTarget = Facade.Instance.GetTargetByImei(imei);
                }
                catch (Exception ex)
                {
                    Logger.Instance.Fatal(this, "Excepcion: " + ex.Message);
                    Logger.Instance.Fatal(this, "Stack Trace: " + ex.StackTrace);
                } 

                if (currentTarget == null)
                {
                    Logger.Instance.Fatal(this, "No se encontro ningun blanco con el IMEI =" + imei );
                    throw new Exception("No se encontro ningun blanco con el IMEI =" + imei );
                }

                #endregion
                #region Actualizar Coordenadas
                currentTarget.CurrentAltitude = altitude;
                currentTarget.CurrentCooridinate = new Coordinate(latitude, longitude);
                currentTarget.CurrentCourse = course;
                currentTarget.CurrentSpeed = speed;
                currentTarget.CurrentBatteryLevel = batteryLevel;

                Logger.Instance.Info(this, "Actualizando coordenadas " + altitude + " - " + latitude + " - " + longitude + " - " + course + " - " + speed + " - " + batteryLevel);
                try
                {
                    Transaction newTran = new Transaction();
                    newTran.Date = DateTime.Now;
                    newTran.CustomerAssociated = null;
                    newTran.TargetAssociated = currentTarget;
                    newTran.Type = TransactionType.UpdateCoordinatesV2Type;
                    newTran.UserAssociated = null;
                    newTran.Value1 = currentTarget.CurrentAltitude;
                    newTran.Value2 = currentTarget.CurrentCooridinate.Latitude;
                    newTran.Value3 = currentTarget.CurrentCooridinate.Longitude;
                    newTran.Value4 = currentTarget.CurrentCourse;
                    newTran.Value5 = currentTarget.CurrentSpeed;
                    newTran.Value6 = currentTarget.CurrentBatteryLevel;

                    if (currentTarget.Device.Enable == false) { Logger.Instance.Warn(this, "El dispositivo asociado al blanco obtenido esta DESHABILITADO (-2)"); newTran.Result = "02"; }
                    else { newTran.Result = "00"; }

                    Facade.Instance.CreateTransaction(newTran);

                    return (Convert.ToInt32(newTran.Result) * -1);
                }
                catch (Exception ex)
                {
                    Logger.Instance.Fatal(this, "Excepcion: " + ex.Message);
                    Logger.Instance.Fatal(this, "Stack Trace: " + ex.StackTrace);
                    return -3;
                } 
                #endregion
            }
        }

        [WebMethod]
        public bool ValidateImei(string imei)
        {
            Logger.Instance.Info(this,"Validando IMEI " + imei);
            return Facade.Instance.ValidateImei(imei);
        }

        [WebMethod]
        public bool FirstTimeActivation(string imei,
                                        string userName)
        {
            Logger.Instance.Info(this,"Activando nombre de usuario " + userName);
            Facade.Instance.FirstTimeActivationUsername(userName);
            Logger.Instance.Info(this,"Activando IMEI " + imei);
            Facade.Instance.FirstTimeActivationImei(imei, userName);
            return true;
        }

        [WebMethod]
        public bool CreateUserWithImei(string imei, string prospectName, string prospectMail, string prospectPassword = null)
        {
            Customer cust = Facade.Instance.GenerateMemoryCustomer(prospectMail, prospectName, prospectMail, "Surname", (String.IsNullOrEmpty(prospectPassword)?prospectMail + "123456":prospectPassword));
            cust.Id = Facade.Instance.CreateCustomer(cust);
            if (cust.Id == -1)
            {
                return false;
            }
            Device device = Facade.Instance.GenerateMemoryDevice(imei,"NoCodeYet");
            device.Id = Facade.Instance.CreateDevice(device);
            if (device.Id == -1)
            {
                return false;
            }
            Target targ = Facade.Instance.GenerateMemoryTarget(prospectMail + imei, cust, device);
            targ.Id = Facade.Instance.CreateTarget(targ);
            if (targ.Id == -1)
            {
                return false;
            }

            return true;

        }

        [WebMethod]
        public bool SendActivationCompletedMail(string mailAddressee)
        {
            bool boolReturn = false;
            Transaction newTrans = new Transaction
            {
                Date = DateTime.Now,
                Result = null,
                TargetAssociated = null,
                UserAssociated = null,
                Type = TransactionType.ActivationCompletedMailNotificationType,
                Value1 = mailAddressee,
                Value2 = null,
                Value3 = null,
                Value4 = null,
                Value5 = null,
                Value6 = null,
                CustomerAssociated = null
            };

            try
            {
                boolReturn = Facade.Instance.SendActivationCompletedMail(mailAddressee);
                if (boolReturn == true)
                {
                    newTrans.Result = "00";
                }
                else
                {
                    newTrans.Result = "01";
                }
            }
            catch(Exception ex)
            {
                Logger.Instance.Fatal(this, "Excepcion: " + ex.Message);
                Logger.Instance.Fatal(this, "Stack Trace: " + ex.StackTrace);
                newTrans.Result = "02";
            }

            try
            {
                Facade.Instance.CreateTransaction(newTrans);
            }
            catch (Exception ex2)
            {
                Logger.Instance.Fatal(this, "Excepcion2: " + ex2.Message);
                Logger.Instance.Fatal(this, "Stack Trace2: " + ex2.StackTrace);
            }


            return boolReturn;
        }

        [WebMethod]
        public bool IsFirstTimeActivation(string userName)
        {
            Logger.Instance.Info(this,"Validando necesidad de activacion por primera vez para usuario " + userName);
            return Facade.Instance.IsFirstTimeActivation(userName);
        }
    }
}
